package com.fool
{
	import flash.events.MouseEvent;

	
	import mx.containers.Panel;
	import mx.containers.VBox;
	import mx.controls.List;
	import mx.core.Application;
	import mx.formatters.DateFormatter;

	public class Game extends Panel
	{
		import com.fool.*;
		
		import mx.collections.*;
		import mx.controls.Alert;
		import mx.events.FlexEvent;
		
		/* status information */
		[Bindable] public var deck:Deck;
		[Bindable] public var user:User;
		[Bindable] public var opponent:Opponent;
		[Bindable] public var table:Table;
		[Bindable] public var trump:Card;
		[Bindable] public var log:String;
		[Bindable] public var logData:String = '';
		
		[Bindable] public var config:Configuration; //private
		private var throwMode:Boolean;
		
		protected function onCretionComplete():void
		{
			user = new User("Vitalik");
			opponent = new Opponent("Computer");
			deck = new Deck();
			table = new Table();
			
			config = new Configuration(user, opponent, deck, table);
			
			deck.invalidate();	//set Values for each card
			trump = deck.getTrumpCard();
			
			loggg("Ты ходишь первым "+ user.name);
			invalidateAttacking(false);
		}
		
		private function invalidateAttacking(tooglePlayer:Boolean = false):void
		{
			currentState = 'blank';
			
			table.clear();
			
			rechargeCards(user.isAttacking);
			
			if (tooglePlayer)
			{
				user.isAttacking = !user.isAttacking;
				
				if (user.isAttacking)
				{
					loggg("Сейчас твой ход. Ты ходиш к игроку " + opponent.name)
				}
			}
		}
		
		//поповнити баланс карт
		private function rechargeCards(userFirst:Boolean = false):void
		{
			var sequence:Array = [user, opponent];
			if ( !userFirst )
			{
				sequence.reverse();
			}
			
			for each (var player:Player in sequence) 
			{
				if (player.necessaryCardsCount > 0)
				{
					var cards:Array = deck.getCards(player.necessaryCardsCount)
					player.recive( new ArrayCollection(cards) );
				}
				player.resetHighlits();
			}
		}
		
		private function pushCardOnTheTable(card:Card, player:Player):void
		{
			player.getCard(card)
			table.put(card);
		}
		
		protected function onSelectCard(event:MouseEvent):void
		{
			var card:Card = (event.currentTarget as List).selectedItem as Card; //ruby by ID
			var valid:Boolean = user.valid(card, table.getData() )
			trace("valid", valid)
			if ( !valid )
			{
				return; //check is card valide for answer
			}
			
			//rubby: get 
			pushCardOnTheTable(card, user);
			if (throwMode)
			{
				return; //only 
			}
			
			//restore from this point
			
			(user.isAttacking) ?
				defineUsersAttacking(card):
				defineUsersDefending(card);
			
			config.saveState(); //save result  
			
		}
		
		private function defineUsersAttacking(card:Card):void
		{
			var responseCard:Card = opponent.desideDefending(card); //response of get
			
			if (responseCard)
			{
				loggg(opponent.name + " отбился картой "+ responseCard.toCardString() +". Сейчас твой ход" );
				pushCardOnTheTable(responseCard, opponent)
				currentState = "rebound";
			}
			else
			{
				loggg(opponent.name+" забирает карту");
				throwMode = true;
				currentState = "goOn"
			}
			
			user.highlithAttackingCards( table.getData() );			
			var code:int = checkIsFinal();//TODO:handle finish of the game	
		}
		

		
		private function defineUsersDefending(responseCard:Card):void
		{
			var attackingCard:Card = opponent.decideAttack( table.getData(), deck.empty );
			if (attackingCard)
			{
				loggg(opponent.name + " сделал ход картой "+ attackingCard.toCardString()+". Сейчас твой ход" )
				pushCardOnTheTable(attackingCard, opponent);
				markDefendingCards(attackingCard);
			}
			else
			{
				invalidateAttacking(true);//auto toogle
			}
			var code:int = checkIsFinal();//TODO:handle finish of the game	
		}
		
		private function updateRestriction(item:*, index:int, array:Array):void 
		{
			var card:SimpleCard = item as SimpleCard;
			card.isTrump = (card.suit == trump.suit)
		}
		
		private function removeFromList(list:ArrayCollection, item:Card):void
		{
			var index:int = list.getItemIndex(item);//TODO: in Ryby:var index:int = player.indexOf(target);
			list.removeItemAt(index); //player.splice(index, 1);
		}
		
		protected function onRebound():void
		{
			loggg("Отбой");
			invalidateAttacking(true);
			
			var card:Card = opponent.getCardWithMinValue(); 
			loggg(opponent.name + " сделал ход картой "+ card.toCardString() +". Сейчас твой ход" )
			pushCardOnTheTable(card, opponent);
			markDefendingCards(card);//mark disabled cards
			currentState = 'getAll';
		}
		
		private function markDefendingCards(card:Card):void
		{
			var defendingList:Array = user.getListOfDefendingCards(card);
			if ( Util.isEmpty(defendingList) && checkIsFinal() != -1)
			{ 
				currentState =  "goOn"; //проіграш  / або виграш
			}
		}
		
		
		//handle finish of the game	
		private function checkIsFinal():int
		{
			var resultCode:int = -1;
			if ( deck.empty )
			{
				if ( user.empty  || opponent.empty )
				{
					var message:String = ''
					if ( user.empty && opponent.empty)
					{
						resultCode = Enum.DRAW;
						message = "Draw";
					}
					else  
					{
						if ( user.empty  )
						{
							resultCode = Enum.USER_WIN
							message = user.name;	
						}else
						{
							resultCode = Enum.USER_DEFEAT;
							message = opponent.name;	
							//disable all cards
						}
					}
					
					currentState ="blank"; //Копка виход
					Alert.show("This is Final! " + message + " Win");
				}
			}
			
			return resultCode;
		}
		
		protected function onGoOn():void
		{
			throwMode = false;
			opponent.putAll( table.reciveAll() );
			loggg(opponent.name + " забирал карту")
			invalidateAttacking();
		}
		
		protected function onGetAll():void
		{
			loggg("Ты снял карты" + table.getData().join())
			user.putAll( table.reciveAll() );
			
			//Move to function
			invalidateAttacking(); 
			
			var card:Card = opponent.getCardWithMinValue(); 
			pushCardOnTheTable(card, opponent);
			//mark disabled cards
			markDefendingCards(card);
			
			currentState = 'getAll';
		}
		
		//private	var df:DateTimeFormatter = new DateTimeFormatter(LocaleID.DEFAULT, DateTimeStyle.NONE, DateTimeStyle.MEDIUM);
		private function loggg(message:String):void
		{
			var timestamp:String = new Date().toDateString(); //df.format(new Date()) ;
			timestamp += '\t'
			logData = timestamp + message + '\n' + logData;
		}
		
	}
}